/*
 * ConfManager.java
 *
 * Version:
 *      $Id: ConfManager.java 19 2009-04-04 21:54:46Z PErickson87 $
 *
 * Copyright (c) 2009 Peter O. Erickson
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without major
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, and/or distribute copies of, but
 * under no circumstances sublicense and/or sell, the Software,
 * and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

package edu.rit.poe.cluster.server;

import edu.rit.poe.cluster.BackendNode;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * This class is the configuration manager for the JCluster application, that
 * loads the configuration properties from a file and provides the rest of the
 * application with the values for configuration properties.
 *
 * @author  Peter O. Erickson
 *
 * @version $Id: ConfManager.java 19 2009-04-04 21:54:46Z PErickson87 $
 */
public final class ConfManager {
    
    /** The default configuration filename. */
    public static final String DEFAULT_CONFIG_FILE = "jcluster.conf";
    
    /** The port to run the job server on. */
    private int jobport;
    
    /** The port to connect to nodes at. */
    private int nodeport;
    
    /** The port to run the HTTP server on. */
    private int httpport;
    
    /** List of hostnames of cluster nodes. */
    private List<String> hosts;
    
    /**
     * Constructs a new <tt>ConfManager</tt>.
     */
    public ConfManager() {
        hosts = new ArrayList<String>();
        jobport = JobServer.DEFAULT_PORT;
        nodeport = BackendNode.JOB_SERVER_PORT;
        httpport = JobServer.DEFAULT_HTTP_PORT;
    }
    
    /**
     * Opens the configuration file and loads all properties.
     * <p>
     * This method opens the default file, and is the same as calling:<br>
     * <tt>configManager.open( ConfigurationManager.DEFAULT_CONFIG_FILE );</tt>
     * 
     * @throws  FileNotFoundException   if the host file is not found
     * @throws  IOException             if there is any error parsing the file
     */
    public void open() throws FileNotFoundException, IOException {
        this.open( DEFAULT_CONFIG_FILE );
    }
    
    /**
     * Opens the configuration file and loads all properties.
     * 
     * @param   filename                the filename of the configuration file
     * 
     * @throws  FileNotFoundException   if the host file is not found
     * @throws  IOException             if there is any error parsing the file
     */
    public void open( String filename ) throws FileNotFoundException,
            IOException {
        
        // opens the file - throw all errors
        BufferedReader in = new BufferedReader( new FileReader( filename ) );
        
        // loop over the file
        String line = null;
        String[] args = null;
        String ident = null;
        while ( ( line = in.readLine() ) != null ) {
            // split the line on spaces
            args = line.split( "\\s+" );
            ident = args[ 0 ];
            if ( ( line.equals( "" ) ) || ( ident.equals( "#" ) ) ) {
                // skip blank lines & comments
                continue;
                
            } else if ( ident.equals( "node" ) ) {
                // add the hostname to the list
                hosts.add( args[ 1 ] );
            } else {
                // unidentified line
                System.err.println( "Unknown start of line: " + ident );
            }
        }
        in.close();
    }
    
    /**
     * Returns a list of hostnames for the nodes in the cluster.
     * 
     * @return  a list of node hostnames
     */
    public List<String> getNodeHostnames() {
        return hosts;
    }
    
    /**
     * Returns the number of nodes in the cluster.
     * 
     * @return  the number of nodes in the cluster
     */
    public int getClusteSize() {
        return hosts.size();
    }
    
    public int getJobPort() {
        return jobport;
    }
    
    public int getNodePort() {
        return nodeport;
    }
    
    public int getHTTPPort() {
        return httpport;
    }
    
} // ConfManager
